import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'dart:ui';
import 'package:chatai/base/base_page_widget.dart';
import 'package:chatai/chat/widgets/chat_input_speech_widget.dart';
import 'package:chatai/main.dart';
import 'package:chatai/theme/theme_colors.dart';
import 'package:chatai/util/common/permission_handler.dart';
import 'package:chatai/util/events.dart';
import 'package:chatai/util/page_constant.dart';
import 'package:chatai/util/widget/common_alert.dart';
import 'package:chatai/provider/chat_count_provider.dart';
import 'package:chatai/user/model/login_service.dart';
import 'package:chatai/provider/user_info_manager.dart';
import 'package:chatai/util/common/object_util.dart';
import 'package:chatai/util/constant.dart';
import 'package:chatai/util/network/network_config.dart';
import 'package:chatai/util/route/index_lifecycle/index_lifecycle_mixin.dart';
import 'package:chatai/util/route/navigator_util.dart';
import 'package:chatai/util/route/routes.dart';
import 'package:chatai/util/sqlite/model/_message.dart';
import 'package:chatai/util/sqlite/realm_dao.dart';
import 'package:chatai/util/store/store.dart';
import 'package:chatai/util/util.dart';
import 'package:chatai/util/widget/easy_refresh_footer.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:chatai/chat/model/chat_model.dart';
import 'package:chatai/chat/widgets/message_in.dart';
import 'package:chatai/chat/widgets/message_out.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_vibrate/flutter_vibrate.dart';
import 'package:provider/provider.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
import 'package:chatai/chat/widgets/chat_input_loading.dart';
import 'package:chatai/chat/utils/chat_utils.dart';

class ChatPage extends BaseStatefulWidget {
  const ChatPage({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() => ChatState();

  static double bottomBarHeight = 0.0;
}

class ChatState extends BaseState<ChatPage>
    with WidgetsBindingObserver, TickerProviderStateMixin, IndexLifecycle {
  late ChatModel _model;
  final FocusNode _focusNode = FocusNode();
  final EasyRefreshController _controller = EasyRefreshController();
  late StreamSubscription<ChatInputLoadingStateEvent>
      _inputLoadingStateSubscription;
  late StreamSubscription<ChatInputUIStateEvent> _chatInputUIStateSubscription;

  // 用户触发列表滑动
  bool isUserScrolling = false;

  // 是否滑动到底部
  bool isBottom = false;

  //
  bool noMore = false;

  late StreamSubscription<bool> keyboardSubscription;
  double inputViewTop = 10.w;
  double topBarHeight = 0.0;
  double defaultBottomBarHeight = 0.0;
  final double _contentMargin = 16.w;
  final double _inputTextFieldMargin = 10.w;
  final double _iconWidth = 26.w;
  final double _inputTextFieldContentHorizontal = 10.w;

  late AnimationController _animationController;
  late Animation<double> _animation;

  _dismissKeyBoard() {
    if (_focusNode.hasFocus) {
      _focusNode.unfocus();
    }
    hideSpeechWidget();
    _model.keyBoardShowType = KeyBoardShowType.no;
  }

  @override
  void initState() {
    super.initState();
    _model = ChatModel();
    _model.init();
    _initAnyListener();
    WidgetsBinding.instance.addObserver(this);
    // 动画相关初始化
    _animationController = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 100));
    _animation = Tween(begin: 0.w, end: 238.w - Constant.bottomBarHeight)
        .animate(_animationController);
  }

  //初始化各种监听
  _initAnyListener(){
    // 消息列表滑动监听
    _model.scrollController.addListener(() {
      // 手动滑动 todo 滑动是否取消选中（）
      if (_model.scrollController.position.userScrollDirection ==
          ScrollDirection.reverse ||
          _model.scrollController.position.userScrollDirection ==
              ScrollDirection.forward) {
        if (!isUserScrolling) {
          isUserScrolling = true;
          _dismissKeyBoard();
        }
      }
    });
    //输入框 焦点监听
    _focusNode.addListener(() {
      if (_focusNode.hasFocus) {
        hideSpeechWidget();
      }
    });
    //键盘监听
    var keyboardVisibilityController = KeyboardVisibilityController();
    keyboardSubscription = keyboardVisibilityController.onChange.listen((bool visible) async {
      formatPrint('键盘状态:$visible');
      if (!visible) {
        _focusNode.unfocus();
      } else {
        _model.scrollController.jumpTo(0);
        _model.keyBoardShowType = KeyBoardShowType.keyBoard;
      }
    });
  }


  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _focusNode.dispose();
    _model.dispose();
    _animationController.dispose();
    keyboardSubscription.cancel();
    _inputLoadingStateSubscription.cancel();
    _chatInputUIStateSubscription.cancel();
    super.dispose();
  }

  @override
  String? title() {
    return '多变';
  }

  @override
  bool hiddenBackIcon() {
    return true;
  }

  @override
  Widget buildBody() {
    return ChangeNotifierProvider.value(
        value: _model,
        child: Selector<ChatModel, int>(
          builder: (context, messageLength, _) {
            formatPrint("app ---------");
            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Expanded(
                  child: InkWell(
                    onTap: () async {
                      if(_showLoading()) return;
                      hideSpeechWidget();
                      context.read<ChatCountProvider>().requestFocus(context);
                    },
                    child: GestureDetector(
                      onPanUpdate: (detail) {
                        if(_showLoading()) return;
                        _dismissKeyBoard();
                      },
                      child: Container(
                        color: ThemeColors.Color_FFFFFF,
                        alignment: Alignment.topCenter,
                        child: NotificationListener(
                            onNotification: _onNotification,
                            child:EasyRefresh(
                                footer: EasyRefreshFooter(),
                                controller: _controller,
                                onLoad: noMore || _model.chatHistory.length < RealmDao.pageSize
                                    ? null
                                    : () async {
                                  bool no = _model.queryMessageList();
                                  if (noMore != no) {
                                    setState(() {
                                      noMore = no;
                                    });
                                  }
                                  _controller.finishLoad();
                                },
                                child: _buildListview(messageLength))),
                      ),
                    ),
                  ),
                ),
                AnimatedBuilder(
                  animation: _animation,
                  builder: (BuildContext btx, Widget? child) {
                    return Container(
                      decoration: BoxDecoration(
                          color: ThemeColors.Color_F2F2F5,
                          boxShadow: const [
                            BoxShadow(
                              color: Color(0x15000000),
                              offset: Offset(0.0, .3),
                              blurRadius: 1.0,
                              //阴影范围
                              blurStyle: BlurStyle.outer,
                              spreadRadius: 0, //阴影浓度
                            ),
                          ],
                          border: Border(
                              bottom: BorderSide(
                                  color: ThemeColors.Color_E5E3E9,
                                  width: 0.5.w))),
                      padding: EdgeInsets.only(
                          left: 0.w,
                          top: inputViewTop,
                          bottom: inputViewTop + _animation.value),
                      child: child!,
                    );
                  },
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: [
                      _textOrMikeInputWidget(),
                      _textFiledWidget(),
                      _sendMessageBtn()
                    ],
                  ),
                ),
              ],
            );
          },
          selector: (_, ChatModel model) => model.chatHistory.length,
          shouldRebuild: (pro, next) => pro != next,
        ));
  }

  /// 输入框左边的按钮： 切换到语音输入
  Widget _textOrMikeInputWidget() {
    return Selector<ChatModel, int>(
      builder: (btx, int inputType, Widget? child) {
        return InkWell(
            onTap: () async {
              if(_showLoading()) return;
              if (_model.inputType == InputType.mike) {
                hideSpeechWidget();
                _focusNode.requestFocus();
              } else {
                //权限申请
                if (await PermissionHandler.checkStorageAndSpeechPermission(
                    context: btx)) {
                  _focusNode.unfocus();
                  _model.createCustomKeyboardOverlayEntry(
                      animation: _animation,
                      controller: _model.textController,
                      callback: _speechBeforeCountLimit,
                      isReceive: _model.sendImageType == ImageType.stop,
                      inputFinishedAction: () {
                        _send();
                      });
                  if (mounted) {
                    _model.showCustomKeyboard(btx);
                    _model.scrollController.jumpTo(0);
                  }
                  _model.inputType = InputType.mike;
                  _model.keyBoardShowType = KeyBoardShowType.speech;
                  Future.delayed(const Duration(milliseconds: 50), () {
                    _animationController.forward();
                  });
                }
              }
            },
            child: Container(
              alignment: Alignment.center,
              padding: EdgeInsets.only(
                  left: _contentMargin, right: _inputTextFieldMargin),
              height: 40.w,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(12.w),
              ),
              child: Image.asset(
                inputType == 0
                    ? "assets/images/chat/speak_mike.png"
                    : "assets/images/chat/speak_keyboard.png",
                width: _iconWidth,
              ),
            ));
      },
      selector: (btx, model) => _model.inputType.index,
      shouldRebuild: (pre, next) => pre != next,
    );
  }

  ///输入框textfield
  Widget _textFiledWidget() {
    return Consumer<ChatModel>(builder: (btx, ChatModel store, Widget? child) {
      return Expanded(
        child: StatefulBuilder(
          builder: (BuildContext contextTextField,
              void Function(void Function()) state) {
            return IntrinsicHeight(
              child: Container(
                  padding: EdgeInsets.only(
                      left: _inputTextFieldContentHorizontal,
                      right: _inputTextFieldContentHorizontal),
                  decoration: BoxDecoration(
                    color: ThemeColors.Color_FFFFFF,
                    borderRadius: BorderRadius.circular(6.w),
                  ),
                  child: Stack(
                    alignment: Alignment.centerLeft,
                    children: [
                      TextField(
                        controller: _model.textController,
                        scrollController: _model.textScrollController,
                        onEditingComplete: () {
                          formatPrint("onEditingComplete");
                        },
                        onChanged: (text) async {
                          Future.delayed(const Duration(milliseconds: 100), () {
                            RenderBox box = contextTextField.findRenderObject()
                                as RenderBox;
                            ChatPage.bottomBarHeight = max(
                                box.size.height + Constant.bottomBarHeight,
                                defaultBottomBarHeight);
                          });
                        },
                        onTap: () async {
                          hideSpeechWidget();
                        },
                        onSubmitted: (text) {
                          formatPrint("onSubmitted");
                        },
                        textAlign: TextAlign.start,
                        maxLines: _model.inputTextFieldMaxLines,
                        cursorColor: ThemeColors.Color_495BFF,
                        minLines: 1,
                        keyboardType: TextInputType.multiline,
                        style: _model.inputTextStyle(),
                        focusNode: _focusNode,
                        decoration: InputDecoration(
                            isDense: true,
                            contentPadding:
                                EdgeInsets.symmetric(vertical: 10.w),
                            hintText: _model.hintText,
                            hintStyle: TextStyle(
                                color: ThemeColors.Color_919899,
                                fontSize: 16,
                                height: 1.5),
                            border: InputBorder.none),
                      ),

                      Selector<ChatModel,bool>(
                          builder: (btx,showLoading,child){
                            return showLoading
                                ? Positioned(
                                    bottom: 0,
                                    left: _model.lastLineWidth,
                                    child: const ChatInputLoading())
                                : const SizedBox.shrink();
                          },
                          selector: (btx,store) => _showLoading(),
                          shouldRebuild: (pre,next) =>  pre != next,
                          )

                    ],
                  )),
            );
          },
        ),
      );
    });
  }

  /// 发送 或者 stop 按钮
  Widget _sendMessageBtn() {
    return Selector<ChatModel, int>(
      builder: (btx, int imageType, Widget? child) {
        return InkWell(
            onTap: () async {
              if(_showLoading()) return;
              if (imageType == ImageType.stop.index) {
                //展示stop时
                await _model.userStopAction();
              } else {
                _send();
              }
            },
            child: Container(
              alignment: Alignment.center,
              padding: EdgeInsets.only(
                  left: _inputTextFieldMargin, right: _contentMargin),
              height: 40.w,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(12.w),
              ),
              child: Image.asset(
                imageType == 2
                    ? "assets/images/chat/stop_light.png"
                    : imageType == 1
                        ? "assets/images/chat/send_light.png"
                        : "assets/images/chat/send_gray.png",
                width: _iconWidth,
              ),
            ));
      },
      selector: (btx, model) => _model.sendImageType.index,
      shouldRebuild: (pre, next) => pre != next,
    );
  }

  // 键盘弹出监听
  @override
  void didChangeMetrics() {
    ///使用keyboardVisibilityController暂时注销
    // _keyboardHidden.then((value) {
    //   if (value) {
    //     _focusNode.unfocus();
    //   } else {
    //     _model.scrollController.jumpTo(0);
    //   }
    // });
  }

  //返回true 代表需要拦截
  bool _speechBeforeCountLimit() {
    if (!UserInfoManage.hasLogin()) {
      int num = Store.valueForKey(Constant.TOUTISTCHATNUMKEY,
          defaultValue: Config.DEFAULTASKNUM);
      if (num <= 0) {
        hideSpeechWidget();
        //次数使用完成。拦截跳登录
        showCommonAlert(
            context: context,
            title: "提示",
            contentText: '您还未登录哦，登录即可享受畅聊',
            confirmText: "登录",
            cancelText: "取消",
            onConfirmTap: () {
              LoginService.shared().tryLogin(context: context);
            });
        return true;
      }
    } else {
      if (!UserInfoManage.isVip()) {
        //普通用户
        if (context.read<ChatCountProvider>().count() <= 0) {
          hideSpeechWidget();

          showCommonAlert(
              context: context,
              title: "提示",
              contentText: '您的使用次数已用完，请升级VIP获取更多次数',
              confirmText: "开通VIP",
              cancelText: "取消",
              onConfirmTap: () {
                NavigatorUtil.push(context, Routes.vipPage,
                    mapParams: {"isNotApplePay": 0});
              });
          return true;
        }
      } else {
        //vip 暂不需要处理
      }
    }
    return false;
  }

  //发送消息具体事件
  _send() {
    if (ObjectUtils.isNotEmpty(_model.textController.text.trim())) {
      if (_speechBeforeCountLimit()) {
        return;
      }
      _model.startSendMessage();
      _focusNode.unfocus();
    }
  }

  void hideSpeechWidget() async {
    if (_model.inputType == InputType.mike) {
      _model.inputType = InputType.text;
      await _animationController.reverse();
      _model.hideCustomKeyboard();
    }
    _model.showInputLoading = false;
  }

  Future<bool> get _keyboardHidden async {
    // 如果窗口底部嵌入值不大于0，说明键盘未显示
    check() => WidgetsBinding.instance.window.viewInsets.bottom <= 0;
    // 如果键盘显示，直接返回结果
    if (!check()) return false;
    // 如果键盘隐藏，为了应对键盘显隐动画过程时导致的误判，等待0.2秒后再次检测，返回结果
    return await Future.delayed(
        const Duration(milliseconds: 300), () => check());
  }

  bool _onNotification(Notification notification) {
    if (notification is ScrollStartNotification) {
      eventBus.fire(ChatListScrollEvent(true));
    } else if (notification is ScrollUpdateNotification) {
    } else if (notification is ScrollEndNotification) {
      eventBus.fire(ChatListScrollEvent(false));
      isUserScrolling = false;
      if (notification.metrics.pixels ==
          _model.scrollController.position.maxScrollExtent) {
        formatPrint('滚动到底部');
      } else {
        formatPrint('非底部');
      }
    }
    return true;
  }


  bool _showLoading() {
    return _model.showInputLoading ||
        (_model.isSpeechInputIng &&
            _model.inputType == InputType.mike &&
            ObjectUtils.isEmpty(_model.textController.text.trim()));
  }

  @override
  int get index => 0;

  @override
  void onHide() {
    formatPrint("--------------aonHide");
  }

  @override
  void onShow() {
    formatPrint("--------------aonShow");
  }

//聊天记录
  Widget _buildListview(int messageLength) {
    return ListView.builder(
        padding: EdgeInsets.only(bottom: 15.w, top: 5.w),
        physics: const BouncingScrollPhysics(),
        controller: _model.scrollController,
        shrinkWrap: true,
        reverse: true,
        itemCount: messageLength,
        itemBuilder: (context, index) {
          Message messageMap = _model.chatHistory[index];
        
          if (messageMap.isSendMessage == 1) {
            return MessageOut(
              message: messageMap,
              topBarHeight: topBarHeight,
            );
          } else {
            return Selector<ChatModel, String>(
              builder:
                  (BuildContext btx, String messageContent, Widget? child) {
                return MessageIn(
                  message: messageMap,
                  ifShowMessage: messageMap.messageStatus == -1,
                  topBarHeight: topBarHeight,
                );
              },
              selector: (btc, ChatModel model) =>
                  model.chatHistory[index].messageContent ?? '',
              shouldRebuild: (previous, next) => previous != next,
            );
          }
        });
  }

  @override
  String pageId() {
    return PageId.chatDetail;
  }

  @override
  String pageName() {
    return PageName.chatDetail;
  }
}
